package war2100.game.states;

import java.util.ArrayList;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

import TWLSlick.BasicTWLGameState;

import war2100.GameConstants;
import war2100.Prototypes;
import war2100.entity.Map;
import war2100.entity.help.BasicHelpEntity;
import war2100.entity.help.PlayerStartPos;
import war2100.entity.npcs.PlayerCharacter;
import war2100.game.GameSession;
import war2100.game.items.ammo.Ammo;

public class GameplayState extends BasicGameState {

	private Map map;
	private GameSession session;
	private Prototypes prototypes;
	private ArrayList<PlayerCharacter> playerList;
	private ArrayList<Ammo> shoots;
	
	public static final int ID = 2;

	public GameplayState(Map map, GameSession session, Prototypes prototypes) {
		super();
		this.map = map;
		this.prototypes = prototypes;
		this.session = session;
		
		playerList = new ArrayList<PlayerCharacter>();
		shoots = new ArrayList<Ammo>();
	}
	
	@Override
	public void init(GameContainer gc, StateBasedGame sbg) throws SlickException {
		ArrayList<PlayerStartPos> playerStartPositions = map.getPlayerStartPos();
		
		for (PlayerStartPos pos : playerStartPositions) {
			if(session.getPlayer(pos.getId()) != null) {
				PlayerCharacter pc = new PlayerCharacter(pos.getX(),pos.getY(),session.getPlayer(pos.getId()),this,prototypes);
				playerList.add(pc);
			}
		}
	}

	@Override
	public void render(GameContainer gc, StateBasedGame sbg, Graphics g) throws SlickException {
		int paintWidth = gc.getWidth();
		int paintHeight = gc.getHeight();

		g.setColor(Color.black);
		g.fillRect(0, 0, paintWidth, paintHeight);

		if (getMap() != null) {
			int fieldWidth = GameConstants.tileXSize;
			int fieldHeight = GameConstants.tileYSize;
			

			if (fieldWidth > fieldHeight)
				fieldWidth = fieldHeight;
			else
				fieldHeight = fieldWidth;

			
			int offsetX = 0;
			int offsetY = 0;
			
			if(getMap().getxSize()*fieldWidth < gc.getWidth())
				offsetX = (gc.getWidth() - getMap().getxSize()*fieldWidth)/2;
			if(getMap().getySize()*fieldHeight < gc.getHeight())
				offsetY = (gc.getHeight() - getMap().getySize()*fieldHeight)/2;
			
			for (int x = 0; x < getMap().getxSize(); x++) {
				for (int y = 0; y < getMap().getySize(); y++) {
					int xPos = offsetX+(fieldWidth * x);
					int yPos = offsetY+(fieldHeight * y);
					getMap().getField(x, y).render(g, xPos, yPos, fieldWidth, fieldHeight);
					// g.drawRect(xPos,yPos,fieldWidth,fieldHeight);
				}
			}

			for (BasicHelpEntity entity : getMap().getEntitys()) {
				if (entity == null) {
					break;
				}
				else if (entity.isVisible()) {
					int x = offsetX+(int)(fieldWidth * entity.getX());
					int y = offsetY+(int)(fieldHeight * entity.getY());
					entity.render(g, x, y, fieldWidth, fieldHeight);
				}
			}
		}

		for (PlayerCharacter pc : playerList) {
			pc.render(g, gc);
		}
		
		for (Ammo pc : getShoots()) {
			pc.render(g, gc);
		}
	}

	@Override
	public void update(GameContainer gc, StateBasedGame sbg, int delta) throws SlickException {
		ArrayList<PlayerCharacter> pl = (ArrayList<PlayerCharacter>)playerList.clone();
		for (PlayerCharacter pc : pl) {
			pc.update(gc, delta);
		}
		
		ArrayList<Ammo> shoot = (ArrayList<Ammo>)getShoots().clone();
		for (Ammo sh : shoot) {
			sh.update(gc, delta);
		}
	}

	@Override
	public int getID() {
		return ID;
	}

	/**
	 * @return the map
	 */
	public Map getMap() {
		return map;
	}

	/**
	 * @param map the map to set
	 */
	public void setMap(Map map) {
		this.map = map;
	}

	/**
	 * @return the shoots
	 */
	public ArrayList<Ammo> getShoots() {
		return shoots;
	}

	/**
	 * @param shoots the shoots to set
	 */
	public void setShoots(ArrayList<Ammo> shoots) {
		this.shoots = shoots;
	}

	/**
	 * @return the prototypes
	 */
	public Prototypes getPrototypes() {
		return prototypes;
	}

	/**
	 * @param prototypes the prototypes to set
	 */
	public void setPrototypes(Prototypes prototypes) {
		this.prototypes = prototypes;
	}

}
